package com.wiz.web.service.impl;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.google.gson.reflect.TypeToken;
import com.wiz.common.util.DateUtil;
import com.wiz.vo.criteria.PayCriteria;
import com.wiz.vo.to.PayOrderTO;
import com.wiz.vo.to.lamicpay.LamicReqData;
import com.wiz.vo.to.lamicpay.LamicResData;
import com.wiz.vo.type.PayMethodType;
import com.wiz.web.dao.mapper.LamicPayMapper;
import com.wiz.web.manager.HttpManager;
import com.wiz.web.manager.fatory.LamicDataFactory;
import com.wiz.web.service.LamicService;

@SuppressWarnings("all")
@Service("lamicService")
public class LamicServiceImpl extends BasicServiceImpl implements LamicService {
	private transient final Logger log = LoggerFactory.getLogger(getClass());
	
	@Resource
	private LamicDataFactory lamicDataFactory;
	@Resource
	private LamicPayMapper lamicPayMapper;
	@Resource
	private HttpManager httpManager;
	
	@Override
	public String lamicBarPay(String order,String hqId,String stationId,String lamicMerchantId,
			String lamicMerchantToken) throws Exception{
		log.info("stationId="+stationId+" using lamicBarPay,params="+order);
		PayCriteria criteria = gson.fromJson(order, new TypeToken<PayCriteria>(){}.getType());
		criteria.setHqId(hqId);
		criteria.setStationId(stationId);
		criteria.setFuellingOrderId(criteria.getOutTradeNo());
		criteria.setOutTradeNo(createLamicOutTradeNo(stationId));
		criteria.setSubMchId(lamicMerchantId);
		LamicReqData reqData = (LamicReqData) lamicDataFactory.getDataByType(criteria,PayMethodType.BAR_PAY.getId(),
				lamicMerchantId,lamicMerchantToken);
		String encryptParams = httpManager.getLamicEncryptResults(reqData.toEncryptParams());
		net.sf.json.JSONObject jsonObject = net.sf.json.JSONObject.fromObject(encryptParams);
		reqData = gson.fromJson(jsonObject.getString("resultMsg"), new TypeToken<LamicReqData>(){}.getType());
		String response = httpManager.sendLamicPost(LAMIC_IP,LAMIC_BAR_PAY, reqData);
//		if(StringUtils.isBlank(response)){
//			return getResponseFromReverse(criteria);
//		}
		LamicResData resData = gson.fromJson(response, new TypeToken<LamicResData>(){}.getType());
		if(resData.getIsResultTrue().equals(LAMIC_TRADE_CODE_SUCCESS)){//支付成功,最终结果需要轮询
			int each = 0;
			LamicResData responseData = null;
			criteria.setTransactionId(resData.getResultMsg());
			Thread.currentThread().sleep(2000);
			LamicReqData queryParams = getEncryptParams(criteria,lamicMerchantId,lamicMerchantToken);
			while(each<4){//30秒后
				response = queryLamicOrder(queryParams);
				responseData = gson.fromJson(response, new TypeToken<LamicResData>(){}.getType());
				if(responseData.getIsResultTrue().equals(LAMIC_TRADE_CODE_SUCCESS)){
					criteria.setResult(response);
					criteria.setPayTime(DateUtil.formatDateTime(System.currentTimeMillis()));
					criteria.setStatus(1);
					lamicPayMapper.insertLamicPayOrder(criteria);
					PayOrderTO orderTO = new PayOrderTO();
					orderTO.setFuellingOrderId(criteria.getFuellingOrderId());
					orderTO.setPayOrderId(criteria.getOutTradeNo());
					orderTO.setRefOrderId(responseData.getResultMsg());
					return returnResult(CODE_OK, STRING_OK, orderTO);
				}
				if(each==3){
					log.info(criteria.getOutTradeNo()+" will Reverse order");
					return getResponseFromReverse(criteria,queryParams,lamicMerchantId,lamicMerchantToken);
				}
				each++;
				Thread.currentThread().sleep(10000);
			}
		}
//		log.warn("stationId="+stationId+"pay fail,response="+resData.getCode()+" || "+resData.getMsg()
//				+",reverseWxOrder will begin after 16s");
//		Thread.currentThread().sleep(16000);
//		criteria.setTransactionId(criteria.getOutTradeNo());
		log.error("Lamic pay fail,reason="+resData.getResultMsg());
		return RESPONSE_LAMIC_FAILED;
	}
	
	/**
	 * 获取加密后参数
	 * @param criteria
	 * @return
	 * @throws Exception
	 */
	private LamicReqData getEncryptParams(PayCriteria criteria,String lamicMerchantId,
			String lamicMerchantToken) throws Exception{
		LamicReqData payData = (LamicReqData) lamicDataFactory.getDataByType(criteria,PayMethodType.QUERY.getId(),
				lamicMerchantId,lamicMerchantToken);
		String encryptParams = httpManager.getLamicEncryptResults(payData.toEncryptParams());
		net.sf.json.JSONObject jsonObject = net.sf.json.JSONObject.fromObject(encryptParams);
		payData = gson.fromJson(jsonObject.getString("resultMsg"), new TypeToken<LamicReqData>(){}.getType());
		return payData;
	}

	/**
	 * 查询莱米订单
	 * @param criteria
	 * @return
	 * @throws Exception 
	 */
	private String queryLamicOrder(LamicReqData queryParams) throws Exception{
		return httpManager.sendLamicPost(LAMIC_IP,LAMIC_BAR_ORDER_SEARCH, queryParams);
	}
	
	/**
	 * 撤销莱米订单
	 * @param criteria
	 * @return
	 * @throws Exception 
	 */
	private LamicResData reverseLamicOrder(PayCriteria criteria,String lamicMerchantId,
			String lamicMerchantToken) throws Exception{
		LamicReqData payData = (LamicReqData) lamicDataFactory.getDataByType(criteria,PayMethodType.REVERSE.getId(),
				lamicMerchantId,lamicMerchantToken);
		String encryptParams = httpManager.getLamicEncryptResults(payData.toEncryptParams());
		net.sf.json.JSONObject jsonObject = net.sf.json.JSONObject.fromObject(encryptParams);
		payData = gson.fromJson(jsonObject.getString("resultMsg"), new TypeToken<LamicReqData>(){}.getType());
		String response = httpManager.sendLamicPost(LAMIC_IP,LAMIC_BAR_REVERSE, payData);
		return gson.fromJson(response, new TypeToken<LamicResData>(){}.getType());
	}
	
	/**
	 * 解析撤销返回结果
	 * @param criteria
	 * @return
	 * @throws Exception 
	 */
	private String getResponseFromReverse(PayCriteria criteria,LamicReqData queryParams,
			String lamicMerchantId,String lamicMerchantToken) throws Exception{
		String response = queryLamicOrder(queryParams);
		LamicResData responseData = responseData = gson.fromJson(response, new TypeToken<LamicResData>(){}.getType());
		if(responseData.getIsResultTrue().equals(LAMIC_TRADE_CODE_SUCCESS)){
			criteria.setResult(response);
			criteria.setPayTime(DateUtil.formatDateTime(System.currentTimeMillis()));
			criteria.setStatus(1);
			lamicPayMapper.insertLamicPayOrder(criteria);
			PayOrderTO orderTO = new PayOrderTO();
			orderTO.setFuellingOrderId(criteria.getFuellingOrderId());
			orderTO.setPayOrderId(criteria.getOutTradeNo());
			orderTO.setRefOrderId(responseData.getResultMsg());
			return returnResult(CODE_OK, STRING_OK, orderTO);
		}else{
			LamicResData responseDataReverse = reverseLamicOrder(criteria,lamicMerchantId,lamicMerchantToken);
			log.info("LAMIC Reverse,result="+responseDataReverse.getIsResultTrue()+","+responseDataReverse.getResultMsg());
		}
		return RESPONSE_LAMIC_FAILED;
	}
	
	/**
	 * 支付订单号
	 * @param stationId
	 * @return
	 */
	private String createLamicOutTradeNo(String stationId){
		return "LC"+stationId+System.currentTimeMillis()+getRandom(5);
	}
}
